﻿using System;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;

namespace 窗口跟随鼠标移动
{
    /**
     * 1、实时获取屏幕鼠标的坐标位置
     * 2、实时获取屏幕鼠标坐标的颜色
     * 3、主窗体实时跟随鼠标位置移动
     **/

    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public struct POINT
        {
            public int x;
            public int y;
        }

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetCursorPos(out POINT lpPoint);

        [DllImport("user32.dll")]
        public static extern IntPtr SetWindowsHookEx(int idHook, LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll")]
        public static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll")]
        public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll")]
        public static extern IntPtr GetModuleHandle(string lpModuleName);

        public const int WH_MOUSE_LL = 14;
        public const int WM_MOUSEMOVE = 0x0200;

        public delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);

        private LowLevelMouseProc _proc;
        private IntPtr _hookID = IntPtr.Zero;

        public MainWindow()
        {
            InitializeComponent();
            // this.MouseMove += Mouse_MouseMove;

            // 为全局鼠标移动监视

            this.Loaded += MainWindow_Loaded;

            // this.LocationChanged += MainWindow_LocationChanged;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            _proc = HookCallback;
            _hookID = SetHook(_proc);
        }

        private IntPtr SetHook(LowLevelMouseProc proc)
        {
            using (var curProcess = System.Diagnostics.Process.GetCurrentProcess())
            using (var curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && wParam == (IntPtr)WM_MOUSEMOVE)
            {
                GetCursorPos(out POINT point);
                string position = $"X:{point.x}, Y:{point.y}";
                Dispatcher.Invoke(() =>
                {
                    System.Drawing.Color color = GetColorAt(point.x, point.y);

                    // 转换 System.Drawing.Color 到 System.Windows.Media.Color
                    var mediaColor = System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B);
                    SolidColorBrush brush = new SolidColorBrush(mediaColor);
                    this.border.Background = brush;

                    // this.point.Text = position + $"Color: #{color.R:X2}{color.G:X2}{color.B:X2}";
                    this.Top = point.y + 5;
                    this.Left = point.x + 5;
                });
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            UnhookWindowsHookEx(_hookID);
        }

        private void MainWindow_LocationChanged(object sender, EventArgs e)
        {
            // Debug.WriteLine(e.GetType().Name.ToString());
        }

        // 获取坐标位置的颜色值
        private System.Drawing.Color GetColorAt(int x, int y)
        {
            using (Bitmap bitmap = new Bitmap(1, 1))
            {
                using (Graphics g = Graphics.FromImage(bitmap))
                {
                    g.CopyFromScreen(x, y, 0, 0, new System.Drawing.Size(1, 1));
                }
                return bitmap.GetPixel(0, 0);
            }
        }

        private void CloseCommand_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            this.Close();
        }

        private void Window_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ChangedButton == MouseButton.Left)
            {
                try
                {
                    this.DragMove();
                }
                catch (InvalidOperationException ex)
                {
                    // 打印日志：处理异常，可能是由于不正确的鼠标事件触发
                    Debug.Write(ex.Message);
                }
            }
        }
    }
}
